/*
 * libFuse.c
 *
 *  Created on: 22/12/2011
 *      Author: utn_so
 */

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <pthread.h>
#include <fuse.h>

#include "libCache.h"
#include "libFileSystem.h"
#include "libFuse.h"
#include "libPaquetes.h"
#include "libSincroDirYArch.h"
#include "utils.h"

#include "tiposFileSystem.h"

#include "log.h"

extern t_fat32_bootSector bootSector;

extern int32_t TAMANIO_CACHE;

extern pthread_mutex_t mutexUsandoCache;

extern int8_t imprimirDebug;
extern int8_t usarFUSE;

int8_t esDir(mode_t mode) {
	return div(div(mode, potencia(2, 15)).rem, potencia(2, 14)).quot;
}

int8_t esArchivoRegular(mode_t mode) {
	return div(div(mode, potencia(2, 16)).rem, potencia(2, 15)).quot;
}

int8_t tienePermisoLectura(mode_t mode) {
	return div(div(mode, potencia(2, 3)).rem, potencia(2, 2)).quot;
}

int8_t tienePermisoEscritura(mode_t mode) {
	return div(div(mode, potencia(2, 2)).rem, potencia(2, 1)).quot;
}

int8_t tienePermisoEjecucion(mode_t mode) {
	return div(mode, potencia(2, 1)).rem;
}

//--------------------FUNCIONES FUSE--------------------//

int32_t FLAME_accessAux(const char* path, int32_t mask) {
	return 0;
}

int32_t FLAME_openAux(const char* path, struct fuse_file_info* fi) {
	infoArchivoODirectorio info;
	div_t division = div(bootSector.rootDirectoryCluster, 256);
	info.clusterHighTwoBytes = division.quot;
	info.clusterLowTwoBytes = division.rem;
	info.attributes = 16;
	if (imprimirDebug) {
		/**/printf("Busco el archivo segun el path: [%s].\n", path);
	}
	int8_t resBusqueda = buscarInfoPathDesdeRaiz((char*) path, &info);
	if (resBusqueda == 0) {
		//PUEDO ABRIR EL ARCHIVO
		if (imprimirDebug) {
			/**/printf("Puedo abrir el archivo.\n");
		}
		pthread_mutex_lock(&mutexUsandoCache);
		if (imprimirDebug) {
			/**/printf("Busco el archivo en la cache.\n");
		}
		t_nodoCache* p = buscarPathEnListaCache(path);
		if (p != NULL) {
			//EL ARCHIVO YA ESTA ABIERTO, AUMENTO LA CANTIDAD DE VECES QUE ESTA ABIERTO
			if (imprimirDebug) {
				/**/printf(
						"El archivo ya habia sido abierto, aumento el file handler.\n");
			}
			p->cantFileDescriptor++;
			(*fi).fh = p->cantFileDescriptor;
			if (imprimirDebug) {
				/**/printf("El file handler vale: [%d].\n",
						p->cantFileDescriptor);
			}
		} else {
			//EL ARCHIVO NO ESTA EN CACHE, LO AGREGO
			if (imprimirDebug) {
				/**/printf("El archivo no habia sido abierto, lo abro.\n");
			}
			uint16_t cantLineasCache =
					TAMANIO_CACHE * 1024
							/ (sizeof(t_lineaCache) - sizeof(uint64_t)
									- sizeof(time_t));
			t_lineaCache* lineasCache = (t_lineaCache*) malloc(
					cantLineasCache * sizeof(t_lineaCache));

			uint32_t i;
			for (i = 0; i < cantLineasCache; i++) {
				lineasCache[i].numBloque = 0;
				memset(lineasCache[i].contenidoBloque, '\0', TAMANIO_BLOQUE);
				lineasCache[i].tiempoAlmacenamiento = time(NULL);
			}
			if (imprimirDebug) {
				/**/printf("Primer bloque: [%d].\n",
						(uint32_t) lineasCache[0].numBloque);
			}
			apilarCache((char*) path, lineasCache);

			(*fi).fh = 1;
		}
		pthread_mutex_unlock(&mutexUsandoCache);
	} else {
		//creo el log para info
		t_log* log = log_create("libFuse", "/home/utn_so/Escritorio/log.txt",
				ERROR, M_CONSOLE_DISABLE);
		log_error(log, "thread_open", "Message error: %s",
				"NO EXISTE EL ARCHIVO");

		return -ENOENT;
	}
}

int32_t FLAME_readdirAux(char *path, void *buf, fuse_fill_dir_t filler,
		off_t offset, struct fuse_file_info *fi) {
	if (imprimirDebug) {
		/**/printf("Se entro en la funcion FLAME_readdir.\n");
	}

	int8_t error = 0;

	infoArchivoODirectorio info;

	div_t division = div(bootSector.rootDirectoryCluster, 256);
	info.clusterHighTwoBytes = division.quot;
	info.clusterLowTwoBytes = division.rem;
	info.attributes = 16;

	if (imprimirDebug) {
		/**/printf("Busco la informacion del directorio [%s].\n", path);
	}

	int8_t resBusqueda = buscarInfoPathDesdeRaiz(path, &info);

	if (imprimirDebug) {
		/**/printf("El resultado de la busqueda fue: [%d].\n", resBusqueda);
	}

	if (resBusqueda == 1) {
		if (imprimirDebug) {
			/**/printf(
					"Se encontro un subdirectorio correspondiente a ese path.\n");
		}
		uint32_t numCluster = deInfoANumCluster(info);

		if (imprimirDebug) {
			/**/printf("El cluster inicial del subdirectorio es: [%d].\n",
					numCluster);
		}

		if (numCluster > 1) {
			if (imprimirDebug) {
				/**/printf("El numero de cluster es mayor a 1.\n");
			}

			if (imprimirDebug) {
				/**/printf(
						"Paso a obtener la cadena de clusters correspondientes.\n");
			}

			nodoCluster* cClustersAuxFte = NULL;
			nodoCluster* cClustersAuxFin = NULL;
			int8_t error = obtenerCadenaClusters(numCluster, &cClustersAuxFte,
					&cClustersAuxFin);
			uint16_t cantClusters = tamanioColaClusters(cClustersAuxFte,
					cClustersAuxFin);
			if (imprimirDebug) {
				/**/printf(
						"La cantidad de clusters correspondientes a la tabla directorio es: [%d].\n",
						cantClusters);
			}

			uint32_t cantRegDir = (cantClusters * bootSector.sectoresCluster
					* bootSector.bytesSector) / sizeof(t_registroDirectorio);
			if (imprimirDebug) {
				/**/printf(
						"La cantidad de registros como maximo que puede tener esta tabla es: [%d].\n",
						cantRegDir);
			}

			if (!error) {

				if (imprimirDebug) {
					/**/printf("Paso a leer la tabla directorio.\n");
				}
				t_registroDirectorio* tablaDirectorio;
				error = leerDirectorio(&cClustersAuxFte, &cClustersAuxFin,
						&tablaDirectorio);

				if (!error) {

					uint32_t i;
					uint8_t j;
					if (imprimirDebug) {
						/**/printf("El contenido del directorio es:\n");
					}
					for (i = 0;
							i < cantRegDir
									&& (tablaDirectorio[i]).fileName[0] != 0;) {
						if (imprimirDebug) {
							/**/printf("Leo el registro[%d].\n", i);
						}
						if ((tablaDirectorio[i]).fileName[0] != 229) {
							//EL REGISTRO NO FUE BORRADO
							if (esSubdirectorio(
									tablaDirectorio[i].fileAttributes)) {
								char* nombre = (char*) malloc(9);
								memset(nombre, '\0', 9);
								memcpy(nombre, tablaDirectorio[i].fileName, 8);
								if (nombre[0] == 5) {
									nombre[0] = 229;
								}
								if (imprimirDebug) {
									/**/printf(
											"En el registro [%d] el subdirectorio: [%s]\n",
											i, nombre);
									/**/printf("(dir)\n");
								}
								if (usarFUSE) {
									filler(buf, nombre, NULL, 0);
								}
								i++;
							} else if (esArchivo(
									tablaDirectorio[i].fileAttributes)) {
								char nombreConExtencion[13];
								memset(nombreConExtencion, '\0', 13);
								unsigned char k;
								for (j = 0, k = 0;
										k < 8
												&& tablaDirectorio[i].fileName[k]
														!= '\0'; j++, k++) {
									if (k == 0
											&& tablaDirectorio[i].fileName[k]
													== 5) {
										nombreConExtencion[j] = 229;
									} else {
										nombreConExtencion[j] =
												tablaDirectorio[i].fileName[k];
									}
								}
								nombreConExtencion[j] = '.';
								j++;
								for (k = 0;
										k < 3
												&& tablaDirectorio[i].fileExtension[k]
														!= '\0'; j++, k++) {
									nombreConExtencion[j] =
											tablaDirectorio[i].fileExtension[k];
								}
								if (imprimirDebug) {
									/**/printf(
											"En el registro [%d] el archivo: [%s]\n",
											i, nombreConExtencion);
								}
								if (usarFUSE) {
									filler(buf, nombreConExtencion, NULL, 0);
								}
								i++;
							} else if (esLongFileName(
									tablaDirectorio[i].fileAttributes)) {
								nodoLongFileName* pLongFileNameFte;
								pLongFileNameFte = NULL;
								t_longFileName longFileName;
								for (;
										esLongFileName(
												tablaDirectorio[i].fileAttributes);
										i++) {
									if (imprimirDebug) {
										/**/printf(
												"El registro [%d] contiene un long file name.\n",
												i);
									}
									deRegDirALongFileName(tablaDirectorio[i],
											&longFileName);
									apilarLongFileName(&pLongFileNameFte,
											longFileName);
								}

								if (imprimirDebug) {
									/**/printf(
											"Contenido de la primera entrada long file name: [%d][%d][%d][%d][%d][%d][%d][%d][%d][%d][%d][%d][%d]\n",
											pLongFileNameFte->longFileName.nameCharacters1[0],
											pLongFileNameFte->longFileName.nameCharacters1[1],
											pLongFileNameFte->longFileName.nameCharacters1[2],
											pLongFileNameFte->longFileName.nameCharacters1[3],
											pLongFileNameFte->longFileName.nameCharacters1[4],
											pLongFileNameFte->longFileName.nameCharacters2[0],
											pLongFileNameFte->longFileName.nameCharacters2[1],
											pLongFileNameFte->longFileName.nameCharacters2[2],
											pLongFileNameFte->longFileName.nameCharacters2[3],
											pLongFileNameFte->longFileName.nameCharacters2[4],
											pLongFileNameFte->longFileName.nameCharacters2[5],
											pLongFileNameFte->longFileName.nameCharacters3[0],
											pLongFileNameFte->longFileName.nameCharacters3[1]);
								}

								char nombre[14];
								memset(nombre, '\0', 14);
								//unsigned char longitud = 0;
								if (imprimirDebug) {
									/**/printf("Obtengo el nombre.\n");
								}
								obtenerNombreLongFileName(pLongFileNameFte,
										nombre);
								if (imprimirDebug) {
									/**/printf("Vacio la pila.\n");
								}
								while (pLongFileNameFte != NULL) {
									desapilarLongFileName(&pLongFileNameFte,
											&longFileName);
									//imprimirYGuardarLongFileName(longFileName, nombre, &longitud); no recordamos si es necesaria
								}
								if (imprimirDebug) {
									/**/printf(
											"En el registro [%d] el long file name: [%s]\n",
											i, nombre);
								}
								/*¿¿¿¿LA EXTENSION ESTA EN EL NOMBRE????
								 printf(".");
								 for (j = 0;
								 ((j < 3)
								 && (tablaDirectorio[i].fileExtension[j] != '\0'));
								 j++) {
								 printf("%c", tablaDirectorio[i].fileExtension[j]);
								 }
								 printf("\n");
								 char nombreConExtencion[18];
								 unsigned char k;
								 for (j = 0, k = 0;
								 k < 13 && tablaDirectorio[i].fileName[k] != '\0';
								 j++, k++) {
								 nombreConExtencion[j] = tablaDirectorio[i].fileName[k];
								 }
								 nombreConExtencion[j] = '.';
								 for (k = 0;
								 k < 3 && tablaDirectorio[i].fileExtension[k] != '\0';
								 j++, k++) {
								 nombreConExtencion[j] = tablaDirectorio[i].fileExtension[k];
								 }
								 nombreConExtencion[k] = '\0';
								 filler(buf, nombreConExtencion, NULL, 0);*/
								if (usarFUSE) {
									filler(buf, (char*) nombre, NULL, 0);
								}
								i++;
							} else {
								if (imprimirDebug) {
									/**/printf("Formato desconocido.\n");
								}
								i++;
							}
						} else {
							if (imprimirDebug) {
								/**/printf(
										"El contenido del registro [%d] fue borrado.\n",
										i);
							}
							i++;
						}
					}
					return 0;
				} else {
					//ERROR AL LEER EL DIRECTORIO
					if (imprimirDebug) {
						/**/printf("Error al leer el directorio.\n");
					}
					return -4;
				}
			} else {
				//ERROR AL OBTENER LA CADENA DE CLUSTERS
				if (imprimirDebug) {
					/**/printf("Error al obtener la cadena de clusters.\n");
				}
				return -3;
			}

		} else if (numCluster == 0) {
			//EL DIRECTORIO ESTA VACIO
			if (imprimirDebug) {
				/**/printf("El directorio esta vacio.\n");
			}
			return 0;
		} else {
			//NUMERO DE CLUSTER INCORRECTO
			if (imprimirDebug) {
				/**/printf("El numero de cluster es menor o igual a 1.\n");
			}
			return -2;
		}
	} else {
		//ERROR AL BUSCAR LA INFORMACION DEL DIRECTORIO
		if (imprimirDebug) {
			/**/printf("Error al buscar la informacion del directorio.\n");
		}
		return -ENOENT;
	}
}

int32_t FLAME_readAux(const char* path, char* buf, size_t size, off_t offset,
		struct fuse_file_info* fi) {

	//CONTADORES
	uint16_t i;
	uint16_t k;

	//IMPRIMO EL PATH PARA DEBUGUEAR
	if (imprimirDebug) {
		printf("[");
		for (i = 0; path[i] != '\0'; i++)
			printf("%c", path[i]);
		printf("]");
	}

	//LEO EL ARCHIVO
	char* contenidoArchivo;
	infoArchivoODirectorio info;
	int64_t res = leerArchivo((char*) path, &contenidoArchivo, &info, offset,
			size);

	//SI NO HUBO ERRORES
	if (res >= 0) {
		for (i = 0; i < res; i++) {
			buf[i] = contenidoArchivo[i];
		}
		return res;
	} else {
		return -1;
	}
}

int32_t FLAME_createAux(const char *path, mode_t modo,
		struct fuse_file_info *fInfo) {
	/*recibe la ruta en la que queremos crear un archivo, y su modo de operacion(r,w)*/

	if (imprimirDebug) {
		/**/printf("Entre en el create.\n");
	}
	int8_t error = 0;

	//OBTENGO LA RUTA DEL DIRECTORIO DONDE QUIERO CREAR EL ARCHIVO
	char* ruta;
	parsearDir((char*) path, &ruta);
	if (imprimirDebug) {
		/**/printf("La ruta del directorio es: [%s].\n", ruta);
	}

	//OBTENGO EL NOMBRE DEL ARCHIVO A CREAR(CON LA EXTENSION)
	char* nombre;
	sacarNombreDeRuta((char*) path, &nombre);
	if (imprimirDebug) {
		/**/printf(
				"El nombre del archivo a crear (con la extension) es: [%s].\n",
				nombre);
	}

	if (strlen(nombre) < 1) {
		//EL NOMBRE DEBE TENER POR LO MENOS UN CARACTER
		if (imprimirDebug) {
			/**/printf("El nombre debe tener por lo menos un caracter.\n");
		}
		return -10;
	}

	if (nombre[0] == 229) {
		//ESTE VALOR SE DEBE REEMPLAZAR, EL PRIMER CARACTER NO PUEDE SER EL 229
		if (imprimirDebug) {
			/**/printf(
					"El primer caracter del nombre no puede ser el [229], se reemplazo por el [5].\n");
		}
		if (imprimirDebug) {
			/**/printf("El nombre quedo: [%s].\n", nombre);
		}
		nombre[0] = 5;
	}

	if (nombre[0] == 46) {
		//EL PRIMER CARACTER NO PUEDE SER EL 46
		if (imprimirDebug) {
			/**/printf("El primer caracter del nombre no puede ser el [46].\n");
		}
		return -9;
	}

	//OBTENGO EL NOMBRE DEL ARCHIVO A CREAR (SIN LA EXTENSION)
	char* nSinExtension;
	parsearNomSinExtension(nombre, &nSinExtension);

	if (imprimirDebug) {
		/**/printf("El nombre del archivo sin la extension es: [%s].\n",
				nSinExtension);
	}

	//OBTENGO LA EXTENSION DEL ARCHIVO
	char* extension;
	parsearExtension(nombre, &extension);

	if (imprimirDebug) {
		/**/printf("La extension del archivo es: [%s].\n", extension);
	}

	//BUSCO LA INFORMACION DEL DIRECTORIO DONDE QUIERO CREAR EL ARCHIVO
	if (imprimirDebug) {
		/**/printf(
				"Busco la informacion del directorio donde voy a crear el archivo.\n");
	}
	infoArchivoODirectorio infoDir;
	div_t division = div(bootSector.rootDirectoryCluster, 256);
	infoDir.clusterHighTwoBytes = division.quot;
	infoDir.clusterLowTwoBytes = division.rem;
	infoDir.attributes = 16;

	int8_t resBusqueda = buscarInfoPathDesdeRaiz(ruta, &infoDir);

	if (imprimirDebug) {
		/**/printf("El resultado de la busqueda fue: [%d].\n", resBusqueda);
	}

	if (resBusqueda == 1) {
		//SE ENCONTRO UN SUBDIRECTORIO CORRESPONDIENTE A ESE PATH
		if (imprimirDebug) {
			/**/printf(
					"Se encontro un subdirectorio correspondiente a ese path.\n");
		}
		uint32_t numCluster = deInfoANumCluster(infoDir);

		if (imprimirDebug) {
			/**/printf("El cluster inicial del subdirectorio es: [%d].\n",
					numCluster);
		}

		if (numCluster > 1) {
			if (imprimirDebug) {
				/**/printf("El numero de cluster es mayor a 1.\n");
			}
			//OBTENGO LOS CLUSTERS CORRESPONDIENTES AL DIRECTORIO
			if (imprimirDebug) {
				/**/printf(
						"Paso a obtener la cadena de clusters correspondientes.\n");
			}
			nodoCluster* colaFte1;
			nodoCluster* colaFin1;
			colaFte1 = NULL;
			colaFin1 = NULL;
			obtenerCadenaClusters(numCluster, &colaFte1, &colaFin1);

			nodoCluster* colaFte2;
			nodoCluster* colaFin2;
			colaFte2 = NULL;
			colaFin2 = NULL;

			nodoCluster* aux = colaFte1;
			while (aux != NULL) {
				encolarCluster(&colaFte2, &colaFin2, aux->numCluster);
				aux = aux->sig;
			}

			//LEO LA TABLA DIRECTORIO
			if (imprimirDebug) {
				/**/printf("Paso a leer la tabla directorio.\n");
			}
			t_registroDirectorio* tablaDir;
			uint16_t cantClusters = tamanioColaClusters(colaFte1, colaFin1);
			if (imprimirDebug) {
				/**/printf(
						"La cantidad de clusters correspondientes a la tabla directorio es: [%d].\n",
						cantClusters);
			}
			uint32_t cantRegDir = (cantClusters * bootSector.sectoresCluster
					* bootSector.bytesSector) / sizeof(t_registroDirectorio);
			if (imprimirDebug) {
				/**/printf(
						"La cantidad de registros como maximo que puede tener esta tabla es: [%d].\n",
						cantRegDir);
			}
			leerDirectorio(&colaFte1, &colaFin1, &tablaDir);
			uint32_t i = 0;

			infoArchivoODirectorio info;

			strcpy(info.name, nSinExtension);
			strcpy(info.extension, extension);

			if (buscarEnDirectorio(tablaDir, &info, cantRegDir) == -1) {
				//SI EL ARCHIVO NO EXISTE EN ESTE DIRECTORIO
				if (imprimirDebug) {
					/**/printf(
							"El archivo no existe en este directorio, puede ser creado.\n");
				}

				if (strlen(nSinExtension) <= 8 && strlen(extension) <= 3) {
					//EL NOMBRE ENTRA EN UN REGISTRO DE DIRECTORIO COMUN, NO ES NECESARIA UNA ENTRADA LONG FILE NAME
					if (imprimirDebug) {
						/**/printf(
								"El nombre entra en un registro de directorio comun, no se necesita una entrada Long File Name.\n");
					}

					while ((i < (cantRegDir)) && (tablaDir[i].fileName[0] != 0)
							&& (tablaDir[i].fileName[0] != 229)) {
						i++;
					}
					if (imprimirDebug) {
						/**/
						if (i < cantRegDir && tablaDir[i].fileName[0] == 0) {
							/**/printf("El registro [%d] esta vacio.\n", i);
							/**/} else if (i < cantRegDir
								&& tablaDir[i].fileName[0] == 229) {
							/**/printf("El registro [%d] fue borrado.\n", i);
							/**/} else {
							/**/printf("La tabla directorio esta completa.\n");
							/**/}
					}
					if ((i < (cantRegDir - 1))
							&& ((tablaDir[i].fileName[0] == 0)
									|| (tablaDir[i].fileName[0] == 229))) {
						//HAY UN LUGAR LIBRE EN LA TABLA DIRECTORIO Y NO ES EL ULTIMO
						if (imprimirDebug) {
							/**/printf(
									"Hay un lugar libre en la tabla directorio y no es el ultimo.\n");
						}

						//CARGO LA INFORMACION DEL ARCHIVO NUEVO
						if (imprimirDebug) {
							/**/printf(
									"Cargo la informacion del archivo nuevo.\n");
						}
						memset(&(tablaDir[i]), 0, sizeof(t_registroDirectorio));
						memcpy(tablaDir[i].fileName, nSinExtension,
								strlen(nSinExtension));
						memcpy(tablaDir[i].fileExtension, extension,
								strlen(extension));

						//AGREGO LOS ATRIBUTOS
						tablaDir[i].fileAttributes = 32;
						if (!tienePermisoEscritura(modo)) {
							tablaDir[i].fileAttributes += 1;
						}
						tablaDir[i].createTimeFineResolution = 0;
						tablaDir[i].createTime = obtenerTime();
						tablaDir[i].createDate = obtenerDate();
						tablaDir[i].lastAccessDate = obtenerDate();
						tablaDir[i].high2BytesOfCluster = 0;
						tablaDir[i].lastModifiedTime = obtenerTime();
						tablaDir[i].lastModifiedDate = obtenerDate();
						tablaDir[i].low2BytesOfCluster = 0;
						tablaDir[i].fileSize = 0;

						//ESCRIBO LA TABLA DIRECTORIO
						if (imprimirDebug) {
							/**/printf("Escribo la tabla directorio.\n");
						}
						error = escribirTablaDirectorio(&colaFte2, &colaFin2,
								tablaDir);

						return error;
					} else {
						//LA TABLA DIRECTORIO ESTA COMPLETAMENTE OCUPADA O SOLO QUEDA EL ULTIMO LUGAR LIBRE
						if (imprimirDebug) {
							/**/printf(
									"La tabla directorio esta completamente ocupada o solo queda un lugar libre.\n");
						}

						//AGREGO UN CLUSTER MAS AL DIRECTORIO
						if (imprimirDebug) {
							/**/printf(
									"Le agrego un cluster mas al directorio.\n");
						}
						error = modificarTablaFat(&colaFte2, &colaFin2,
								cantClusters + 1);

						if (!error) {
							//LLAMO A LA MISMA FUNCION CON EL DIRECTORIO MODIFICADO
							if (imprimirDebug) {
								/**/printf(
										"LLamo a la misma funcion con el directorio modificado.\n");
							}
							int32_t res = FLAME_createAux(path, modo, fInfo);
							return res;
						} else {
							if (imprimirDebug) {
								/**/printf(
										"Error al modificar la tabla fat.\n");
							}
							return error;
						}
					}

				} else {
					//NECESITO UNA ENTRADA LONG FILE NAME
					if (imprimirDebug) {
						/**/printf("Necesito una entrada Long File Name.\n");
					}
					uint32_t regInicio = 0;
					uint32_t cantRegConsecutivos = 0;
					if (imprimirDebug) {
						/**/
						printf(
								"Busco la mayor cantidad de registros libres consecutivos.\n");
					}
					error = mayorCantRegDirConsecutivos(tablaDir, cantRegDir,
							&regInicio, &cantRegConsecutivos);

					if (!error) {
						if (imprimirDebug) {
							/**/printf(
									"A partir del registro [%d] hay [%d] registros libres consecutivos.\n",
									regInicio, cantRegConsecutivos);
						}
						if ((cantRegConsecutivos > 2)
								|| ((cantRegConsecutivos == 2)
										&& (regInicio != cantRegDir - 3))) {
							//HAY LUGAR PARA UNA ENTRADA LONG FILE NAME
							if (imprimirDebug) {
								/**/printf(
										"Hay lugar para una entrada Long File Name.\n");
							}

							//ARMO EL NOMBRE
							char LFN[13];
							memset(LFN, '\0', 13);
							uint8_t j;
							for (j = 0; j < 13 && nombre[j] != '\0'; j++) {
								LFN[j] = nombre[j];
							}

							if (imprimirDebug) {
								/**/
								printf("El nombre del archivo sera: [%s].\n",
										LFN);
							}

							//ARMO EL REGISTRO DE TIPO LFN
							t_longFileName regLFN;

							regLFN.secuenceNumber = 65;

							//PRIMERA PARTE DEL NOMBRE
							size_t longUTF8 = 5;
							size_t longUTF16 = 0;
							unicode_utf8_to_utf16_inbuffer(LFN, longUTF8,
									regLFN.nameCharacters1, &longUTF16);

							regLFN.attributes = 15;

							regLFN.reserved = 0;

							regLFN.checksum = 0;

							//SEGUNDA PARTE DEL NOMBRE
							longUTF8 = 6;
							longUTF16 = 0;
							unicode_utf8_to_utf16_inbuffer(LFN + 5, longUTF8,
									regLFN.nameCharacters2, &longUTF16);

							regLFN.firstCluster = 0;

							//TERCERA PARTE DEL NOMBRE
							longUTF8 = 2;
							longUTF16 = 0;
							unicode_utf8_to_utf16_inbuffer(LFN + 11, longUTF8,
									regLFN.nameCharacters3, &longUTF16);

							if (imprimirDebug) {
								/**/
								printf(
										"El nombre en UTF16 es [%d][%d][%d][%d][%d][%d][%d][%d][%d][%d][%d][%d][%d]",
										regLFN.nameCharacters1[0],
										regLFN.nameCharacters1[1],
										regLFN.nameCharacters1[2],
										regLFN.nameCharacters1[3],
										regLFN.nameCharacters1[4],
										regLFN.nameCharacters2[0],
										regLFN.nameCharacters2[1],
										regLFN.nameCharacters2[2],
										regLFN.nameCharacters2[3],
										regLFN.nameCharacters2[4],
										regLFN.nameCharacters2[5],
										regLFN.nameCharacters3[0],
										regLFN.nameCharacters3[1]);
							}

							guardarLongFileNameEnRegComun(regLFN,
									&(tablaDir[regInicio]));

							memset(&(tablaDir[regInicio + 1]), 0,
									sizeof(t_registroDirectorio));
							memset(tablaDir[regInicio + 1].fileName, 1, 8);
							memset(tablaDir[regInicio + 1].fileExtension, 1, 3);
							tablaDir[regInicio + 1].fileAttributes = 32;
							tablaDir[regInicio + 1].createTimeFineResolution =
									0;
							tablaDir[regInicio + 1].createTime = obtenerTime();
							tablaDir[regInicio + 1].createDate = obtenerDate();
							tablaDir[regInicio + 1].lastAccessDate =
									obtenerDate();
							tablaDir[regInicio + 1].high2BytesOfCluster = 0;
							tablaDir[regInicio + 1].lastModifiedTime =
									obtenerTime();
							tablaDir[regInicio + 1].lastModifiedDate =
									obtenerDate();
							tablaDir[regInicio + 1].low2BytesOfCluster = 0;
							tablaDir[regInicio + 1].fileSize = 0;

							//ESCRIBO LA TABLA DIRECTORIO
							if (imprimirDebug) {
								/**/
								printf("Escribo la tabla directorio.\n");
							}
							error = escribirTablaDirectorio(&colaFte2,
									&colaFin2, tablaDir);

							return error;
						} else {
							//NO HAY LUGAR PARA UNA ENTRADA LONG FILE NAME
							if (imprimirDebug) {
								/**/printf(
										"No hay lugar en la tabla directorio.\n");
							}

							//AGREGO UN CLUSTER MAS AL DIRECTORIO
							if (imprimirDebug) {
								/**/
								printf("Agrego un cluster al directorio.\n");
							}
							error = modificarTablaFat(&colaFte2, &colaFin2,
									cantClusters + 1);

							if (!error) {
								//LLAMO A LA MISMA FUNCION CON EL DIRECTORIO MODIFICADO
								if (imprimirDebug) {
									/**/printf(
											"Llamo a la misma funcion con el directorio modificado.\n");
								}
								int32_t res = FLAME_createAux(path, modo,
										fInfo);
								return res;
							} else {
								if (imprimirDebug) {
									/**/printf(
											"Error al modificar la tabla fat.\n");
								}
								return error;
							}
						}
					} else {
						if (imprimirDebug) {
							/**/printf(
									"Error al obtener la mayor cantidad de registros consecutivos.\n");
						}
						return error;
					}
				}

			} else {
				//EL ARCHIVO YA EXISTE
				if (imprimirDebug) {
					/**/printf("El archivo ya existe.\n");
				}
				return -8;
			}
		} else {
			if (imprimirDebug) {
				/**/printf("El numero de cluster es menor o igual a 1.\n");
			}
			return -7;
		}
	} else {
		//ERROR AL BUSCAR EL DIRECTORIO
		if (imprimirDebug) {
			/**/printf("Error al buscar el directorio.\n");
		}
		return -ENOENT;
	}
}

int32_t FLAME_mkdirAux(const char *path, mode_t modo) {
	if (imprimirDebug) {
		/**/printf("Entre en el mkdir.\n");
	}

	int8_t error = 0;

	//OBTENGO LA RUTA DEL DIRECTORIO DONDE QUIERO CREAR EL SUBDIRECTORIO
	char* ruta;
	parsearDir((char*) path, &ruta);
	if (imprimirDebug) {
		/**/
		printf("La ruta del directorio es: [%s].\n", ruta);
	}

	//OBTENGO EL NOMBRE DEL DIRECTORIO A CREAR
	char* nombre;
	sacarNombreDeRuta((char*) path, &nombre);
	if (imprimirDebug) {
		/**/
		printf("El nombre del directorio a crear es: [%s].\n", nombre);
	}

	if (strlen(nombre) < 1) {
		//EL NOMBRE DEBE TENER POR LO MENOS UN CARACTER
		if (imprimirDebug) {
			/**/printf("El nombre debe tener por lo menos un caracter.\n");
		}
		return -1;
	}

	if (nombre[0] == 229) {
		//ESTE VALOR SE DEBE REEMPLAZAR, EL PRIMER CARACTER NO PUEDE SER EL 229
		if (imprimirDebug) {
			/**/printf(
					"El primer caracter del nombre no puede ser el [229], se reemplazo por el [5].\n");
		}
		if (imprimirDebug) {
			/**/printf("El nombre quedo: [%s].\n", nombre);
		}
		nombre[0] = 5;
	}

	if (nombre[0] == 46) {
		//EL PRIMER CARACTER NO PUEDE SER EL 46
		if (imprimirDebug) {
			/**/printf("El primer caracter del nombre no puede ser el [46].\n");
		}
		return -1;
	}

	//BUSCO LA INFORMACION DEL DIRECTORIO DONDE QUIERO CREAR EL SUBDIRECTORIO
	if (imprimirDebug) {
		/**/
		printf(
				"Busco la informacion del directorio donde voy a crear el subdirectorio.\n");
	}
	infoArchivoODirectorio infoDir;
	div_t division = div(bootSector.rootDirectoryCluster, 256);
	infoDir.clusterHighTwoBytes = division.quot;
	infoDir.clusterLowTwoBytes = division.rem;
	infoDir.attributes = 16;

	int8_t resBusqueda = buscarInfoPathDesdeRaiz(ruta, &infoDir);

	if (imprimirDebug) {
		/**/
		printf("El resultado de la busqueda fue: [%d].\n", resBusqueda);
	}

	if (resBusqueda == 1) {
		//SE ENCONTRO UN SUBDIRECTORIO CORRESPONDIENTE A ESE PATH
		if (imprimirDebug) {
			/**/printf(
					"Se encontro un subdirectorio correspondiente a ese path.\n");
		}
		uint32_t numCluster = deInfoANumCluster(infoDir);
		if (imprimirDebug) {
			/**/
			printf("El cluster inicial del subdirectorio es: [%d].\n",
					numCluster);
		}

		if (numCluster > 1) {
			if (imprimirDebug) {
				/**/printf("El numero de cluster es mayor a 1.\n");
			}
			//OBTENGO LOS CLUSTERS CORRESPONDIENTES AL DIRECTORIO
			if (imprimirDebug) {
				/**/
				printf(
						"Paso a obtener la cadena de clusters correspondientes.\n");
			}
			nodoCluster* colaFte1;
			nodoCluster* colaFin1;
			colaFte1 = NULL;
			colaFin1 = NULL;
			obtenerCadenaClusters(numCluster, &colaFte1, &colaFin1);

			nodoCluster* colaFte2;
			nodoCluster* colaFin2;
			colaFte2 = NULL;
			colaFin2 = NULL;

			nodoCluster* aux = colaFte1;
			while (aux != NULL) {
				encolarCluster(&colaFte2, &colaFin2, aux->numCluster);
				aux = aux->sig;
			}

			//LEO LA TABLA DIRECTORIO
			if (imprimirDebug) {
				/**/
				printf("Paso a leer la tabla directorio.\n");
			}
			t_registroDirectorio* tablaDir;
			uint16_t cantClusters = tamanioColaClusters(colaFte1, colaFin1);
			if (imprimirDebug) {
				/**/
				printf(
						"La cantidad de clusters correspondientes a la tabla directorio es: [%d].\n",
						cantClusters);
			}
			uint32_t cantRegDir = (cantClusters * bootSector.sectoresCluster
					* bootSector.bytesSector) / sizeof(t_registroDirectorio);
			if (imprimirDebug) {
				/**/
				printf(
						"La cantidad de registros como maximo que puede tener esta tabla es: [%d].\n",
						cantRegDir);
			}
			leerDirectorio(&colaFte1, &colaFin1, &tablaDir);
			uint32_t i = 0;

			infoArchivoODirectorio info;

			strcpy(info.name, nombre);
			memset(info.extension, '\0', 13);

			if (buscarEnDirectorio(tablaDir, &info, cantRegDir) == -1) {
				//SI EL SUBDIRECTORIO NO EXISTE EN ESTE DIRECTORIO
				if (imprimirDebug) {
					/**/printf(
							"El subdirectorio no existe en este directorio, puede ser creado.\n");
				}

				if (strlen(nombre) <= 8) {
					//EL NOMBRE ENTRA EN UN REGISTRO DE DIRECTORIO COMUN
					if (imprimirDebug) {
						/**/printf(
								"El nombre entra en un registro de directorio comun, no se necesita una entrada Long File Name.\n");
					}

					while ((i < (cantRegDir)) && (tablaDir[i].fileName[0] != 0)
							&& (tablaDir[i].fileName[0] != 229)) {
						i++;
					}
					if (imprimirDebug) {
						/**/
						if (i < cantRegDir && tablaDir[i].fileName[0] == 0) {
							/**/printf("El registro [%d] esta vacio.\n", i);
							/**/} else if (i < cantRegDir
								&& tablaDir[i].fileName[0] == 229) {
							/**/printf("El registro [%d] fue borrado.\n", i);
							/**/} else {
							/**/printf("La tabla directorio esta completa.\n");
							/**/}
					}
					if ((i < (cantRegDir - 1))
							&& ((tablaDir[i].fileName[0] == 0)
									|| (tablaDir[i].fileName[0] == 229))) {
						//HAY UN LUGAR LIBRE EN LA TABLA DIRECTORIO Y NO ES EL ULTIMO
						if (imprimirDebug) {
							/**/printf(
									"Hay un lugar libre en la tabla directorio y no es el ultimo.\n");
						}

						uint32_t numClusterLibre = obtenerClusterLibre();
						if (imprimirDebug) {
							/**/
							printf(
									"Se encontro que el cluster [%d] esta libre.\n",
									numClusterLibre);
						}

						if (numClusterLibre > 1) {
							if (imprimirDebug) {
								/**/printf(
										"El numero de cluster libre es mayor a 1.\n");
							}

							//SE ENCONTRO UN CLUSTER LIBRE EN LA TABLA FAT
							division = div(numClusterLibre, 256);

							//CARGO LA INFORMACION DEL SUBDIRECTORIO NUEVO
							if (imprimirDebug) {
								/**/
								printf(
										"Cargo la informacion del archivo nuevo.\n");
							}
							memset(&(tablaDir[i]), 0,
									sizeof(t_registroDirectorio));
							memcpy(tablaDir[i].fileName, nombre,
									strlen(nombre));

							//SE AGREGAN LOS ATRIBUTOS
							tablaDir[i].fileAttributes = 16;
							if (!tienePermisoEscritura(modo)) {
								tablaDir[i].fileAttributes += 1;
							}

							tablaDir[i].createTimeFineResolution = 0;
							tablaDir[i].createTime = obtenerTime();
							tablaDir[i].createDate = obtenerDate();
							tablaDir[i].lastAccessDate = obtenerDate();
							tablaDir[i].high2BytesOfCluster = division.quot;
							tablaDir[i].lastModifiedTime = obtenerTime();
							tablaDir[i].lastModifiedDate = obtenerDate();
							tablaDir[i].low2BytesOfCluster = division.rem;
							tablaDir[i].fileSize = 0;

							//ESCRIBO LA TABLA DIRECTORIO
							if (imprimirDebug) {
								/**/
								printf("Escribo la tabla directorio.\n");
							}
							error = escribirTablaDirectorio(&colaFte2,
									&colaFin2, tablaDir);

							return error;
						} else {
							//EL NUMERO DE CLUSTER ES MENOR O IGUAL A 1
							if (imprimirDebug) {
								/**/printf(
										"El numero de cluster es menor o igual a 1.\n");
							}
							return -5;
						}
					} else {
						//LA TABLA DIRECTORIO ESTA COMPLETAMENTE OCUPADA O SOLO QUEDA EL ULTIMO LUGAR LIBRE
						if (imprimirDebug) {
							/**/printf(
									"La tabla directorio esta completamente ocupada o solo queda un lugar libre.\n");
						}

						//AGREGO UN CLUSTER MAS AL DIRECTORIO
						if (imprimirDebug) {
							/**/
							printf("Le agrego un cluster mas al directorio.\n");
						}
						error = modificarTablaFat(&colaFte2, &colaFin2,
								cantClusters + 1);

						if (!error) {
							//LLAMO A LA MISMA FUNCION CON EL DIRECTORIO MODIFICADO
							if (imprimirDebug) {
								/**/printf(
										"LLamo a la misma funcion con el directorio modificado.\n");
							}

							int32_t res = FLAME_mkdirAux(path, modo);
							return res;
						} else {
							if (imprimirDebug) {
								/**/printf(
										"Error al modificar la tabla fat.\n");
							}
							return error;
						}
					}
				} else {
					//EL NOMBRE ES MUY LARGO
					if (imprimirDebug) {
						/**/printf(
								"El nombre del subdirectorio es muy largo.\n");
					}
					return -4;
				}

			} else {
				//EL SUBDIRECTORIO YA EXISTE
				if (imprimirDebug) {
					/**/printf("El subdirectorio ya existe.\n");
				}
				return -3;
			}
		} else {
			//EL NUMERO DE CLUSTER ES MENOR O IGUAL A 1
			if (imprimirDebug) {
				/**/printf("El numero de cluster es menor o igual a 1.\n");
			}
			return -2;
		}
	} else {
		//ERROR AL BUSCAR EL DIRECTORIO
		if (imprimirDebug) {
			/**/printf("Error al buscar el directorio.\n");
		}
		return -ENOENT;
	}
}

int32_t FLAME_rmdirAux(const char* path) {
	//OBTENGO LA DIRECCION DEL DIRECTORIO DONDE ESTA EL SUBDIRECTORIO QUE VOY A BORRAR
	char* ruta;
	parsearDir((char*) path, &ruta);

	//OBTENGO EL NOMBRE DEL DIRECTORIO A BORRAR
	char* nombre;
	sacarNombreDeRuta((char*) path, &nombre);

	//BUSCO LA INFORMACION DEL DIRECTORIO
	infoArchivoODirectorio infoDir;
	div_t division = div(bootSector.rootDirectoryCluster, 256);
	infoDir.clusterHighTwoBytes = division.quot;
	infoDir.clusterLowTwoBytes = division.rem;
	infoDir.attributes = 16;

	int8_t resBusqueda = buscarInfoPathDesdeRaiz(ruta, &infoDir);

	if (resBusqueda == 1) {
		//SE ENCONTRO UN SUBDIRECTORIO CORRESPONDIENTE A ESE PATH
		uint32_t numCluster = deInfoANumCluster(infoDir);

		if (numCluster > 1) {
			//OBTENGO LOS CLUSTERS CORRESPONDIENTES AL DIRECTORIO
			nodoCluster* colaFte1;
			nodoCluster* colaFin1;
			colaFte1 = NULL;
			colaFin1 = NULL;
			obtenerCadenaClusters(numCluster, &colaFte1, &colaFin1);

			nodoCluster* colaFte2;
			nodoCluster* colaFin2;
			colaFte2 = NULL;
			colaFin2 = NULL;

			nodoCluster* aux = colaFte1;
			while (aux != NULL) {
				encolarCluster(&colaFte2, &colaFin2, aux->numCluster);
				aux = aux->sig;
			}

			//LEO LA TABLA DIRECTORIO
			t_registroDirectorio* tablaDir;
			uint16_t cantClusters = tamanioColaClusters(colaFte1, colaFin1);
			uint32_t cantRegDir = (cantClusters * bootSector.sectoresCluster
					* bootSector.bytesSector) / sizeof(t_registroDirectorio);
			leerDirectorio(&colaFte1, &colaFin1, &tablaDir);

			infoArchivoODirectorio infoSubDir;

			strcpy(infoSubDir.name, nombre);
			memset(infoSubDir.extension, '\0', 13);

			uint32_t regDir = buscarEnDirectorio(tablaDir, &infoSubDir,
					cantRegDir);

			if (regDir != -1) {
				//SI EL SUBDIRECTORIO EXISTE EN ESTE DIRECTORIO
				uint32_t numClusterSubDir = deInfoANumCluster(infoSubDir);

				//OBTENGO LOS CLUSTERS CORRESPONDIENTES AL SUBDIRECTORIO
				nodoCluster* colaSubDirFte1;
				nodoCluster* colaSubDirFin1;
				colaSubDirFte1 = NULL;
				colaSubDirFin1 = NULL;
				obtenerCadenaClusters(numClusterSubDir, &colaSubDirFte1,
						&colaSubDirFin1);

				nodoCluster* colaSubDirFte2;
				nodoCluster* colaSubDirFin2;
				colaSubDirFte2 = NULL;
				colaSubDirFin2 = NULL;

				nodoCluster* auxSubDir = colaSubDirFte1;
				while (auxSubDir != NULL) {
					encolarCluster(&colaSubDirFte2, &colaSubDirFin2,
							auxSubDir->numCluster);
					auxSubDir = auxSubDir->sig;
				}

				//LEO LA TABLA DIRECTORIO
				t_registroDirectorio* tablaSubDir;
				uint16_t cantClustersSubDir = tamanioColaClusters(
						colaSubDirFte1, colaSubDirFin1);
				uint32_t cantRegSubDir = (cantClustersSubDir
						* bootSector.sectoresCluster * bootSector.bytesSector)
						/ sizeof(t_registroDirectorio);
				leerDirectorio(&colaSubDirFte1, &colaSubDirFin1, &tablaSubDir);

				uint32_t i;
				int8_t vacio = 1;
				for (i = 0; i < cantRegSubDir && vacio; i++) {
					if (tablaSubDir[i].fileName[0] == 0
							|| tablaSubDir[i].fileName[0] == 229) {
						vacio = 1;
					} else {
						vacio = 0;
					}
				}
				if (vacio) {
					int8_t error = 0;
					error = habilitarClusters(&colaSubDirFte2, &colaSubDirFin2);
					if (!error) {
						tablaDir[regDir].fileName[0] = 229;
						error = escribirTablaDirectorio(&colaFte2, &colaFin2,
								tablaDir);
						return error;
					} else {
						//ERROR AL HABILITAR LOS CLUSTERS
						return -5;
					}
				} else {
					//EL SUBDIRECTORIO NO ESTA VACIO
					return -4;
				}

			} else {
				//EL SUBDIRECTORIO NO EXISTE EN ESTE DIRECTORIO
				return -ENOENT;
			}
		} else {
			//EL NUMERO DE CLUSTER ES INCORRECTO
			return -2;
		}
	} else {
		//NO EXISTE EL DIRECTORIO
		return -ENOENT;
	}
}

int32_t FLAME_getattrAux(const char* path, struct stat* stbuf) {
	infoArchivoODirectorio info;
	div_t division = div(bootSector.rootDirectoryCluster, 256);
	info.clusterHighTwoBytes = division.quot;
	info.clusterLowTwoBytes = division.rem;
	info.attributes = 16;

	int8_t resBusqueda = buscarInfoPathDesdeRaiz((char*) path, &info);

	if (resBusqueda == 0 || resBusqueda == 1) {
		//CARGO LA INFORMACION EN EL STBUF
		if (imprimirDebug) {
			/**/printf("Nombre: [%s].\n", info.name);
			/**/
			printf("Extension: [%s].\n", info.extension);
			/**/
			printf("Atributos: [%d].\n", info.attributes);
			/**/
			printf("Reserved: [%d].\n", info.reserved);
			/**/
			printf("Create time fine resolution: [%d].\n",
					info.createTimeFineResolution);
			/**/
			printf("Create time: [%d].\n", info.createTime);
			/**/
			printf("Create date: [%d].\n", info.createDate);
			/**/
			printf("Last access date: [%d].\n", info.lastAccessDate);
			/**/
			printf("High 2 Bytes of Cluster: [%d].\n",
					info.clusterHighTwoBytes);
			/**/
			printf("Last modified time: [%d].\n", info.lastModifiedTime);
			/**/
			printf("Last modified date: [%d].\n", info.lastModifiedDate);
			/**/
			printf("Low 2 Bytes of Cluster: [%d].\n", info.clusterLowTwoBytes);
			/**/
			printf("File Size: [%d].\n", info.size);
		}

		nodoCluster* cClusterFte = NULL;
		nodoCluster* cClusterFin = NULL;

		uint32_t cantClusters;
		uint32_t numCluster = deInfoANumCluster(info);

		if (numCluster > 1) {
			int8_t error = obtenerCadenaClusters(numCluster, &cClusterFte,
					&cClusterFin);
			if (!error) {
				cantClusters = tamanioColaClusters(cClusterFte, cClusterFin);
				while (cClusterFte != NULL) {
					desencolarCluster(&cClusterFte, &cClusterFin, &numCluster);
				}
			} else {
				return -2;
			}
		} else {
			cantClusters = 0;
		}

		(*stbuf).st_dev = 0;

		(*stbuf).st_ino = 0;

		if (resBusqueda == 0) {
			(*stbuf).st_mode = S_IFREG;
		} else {
			(*stbuf).st_mode = S_IFDIR;
		}

		(*stbuf).st_nlink = 0;

		(*stbuf).st_uid = 0;

		(*stbuf).st_gid = 0;

		(*stbuf).st_rdev = 0;

		(*stbuf).st_size = info.size;

		(*stbuf).st_blksize = TAMANIO_BLOQUE;

		(*stbuf).st_blocks = cantClusters;

		/*(*stbuf).st_atim = 0;

		 (*stbuf).st_mtim = 0;

		 (*stbuf).st_ctim = 0;*/

		return 0;
	}
	return -ENOENT;
}

int32_t FLAME_flushAux(const char * path, struct fuse_file_info * info) {
	pthread_mutex_lock(&mutexUsandoCache);
	int8_t error = eliminarCache((char*) path);
	pthread_mutex_unlock(&mutexUsandoCache);
	(*info).flush = 1;
	if (!error) {
		return 0;
	} else if (error == -1) {
		//LA CACHE ESTABA VACIA
		return 0;
	} else if (error == -2) {
		//NO SE ENCONTRO EL ARCHIVO EN LA CACHE
		return 0;
	} else {
		return -1;
	}
}

int32_t FLAME_unlinkAux(const char* path) {
	char* rutaDir;
	parsearDir((char*) path, &rutaDir);
	infoArchivoODirectorio infoDir;
	div_t division = div(bootSector.rootDirectoryCluster, 256);
	infoDir.clusterHighTwoBytes = division.quot;
	infoDir.clusterLowTwoBytes = division.rem;
	infoDir.attributes = 16;
	int8_t error = 0;

	int8_t resBusqueda = buscarInfoPathDesdeRaiz(rutaDir, &infoDir);

	if (resBusqueda == 1) {
		uint32_t numClusterDir = deInfoANumCluster(infoDir);
		nodoCluster* cClusterFte1 = NULL;
		nodoCluster* cClusterFin1 = NULL;
		error = obtenerCadenaClusters(numClusterDir, &cClusterFte1,
				&cClusterFin1);
		nodoCluster* cClusterFte2 = NULL;
		nodoCluster* cClusterFin2 = NULL;
		nodoCluster* aux = cClusterFte1;
		while (aux != NULL && !error) {
			error = encolarCluster(&cClusterFte2, &cClusterFin2,
					aux->numCluster);
			aux = aux->sig;
		}

		if (!error) {

			t_registroDirectorio* tablaDirectorio;
			uint16_t cantRegistrosDirectorio = (tamanioColaClusters(
					cClusterFte1, cClusterFin1) * bootSector.sectoresCluster
					* bootSector.bytesSector) / sizeof(t_registroDirectorio);
			error = leerDirectorio(&cClusterFte1, &cClusterFin1,
					&tablaDirectorio);

			if (!error) {
				char* nombre;
				sacarNombreDeRuta((char*) path, &nombre);
				char* nSinExtension;
				parsearNomSinExtension(nombre, &nSinExtension);
				if (imprimirDebug) {
					/**/
					printf("Nombre del archivo a borrar: [%s].\n",
							nSinExtension);
				}
				char* extension;
				parsearExtension(nombre, &extension);
				if (imprimirDebug) {
					/**/
					printf("Extension del archivo a borrar: [%s].\n",
							extension);
				}
				infoArchivoODirectorio infoArchivo;
				strcpy(infoArchivo.name, nSinExtension);
				strcpy(infoArchivo.extension, extension);
				int8_t resBorrar = borrarFilaDirectorio(tablaDirectorio,
						&infoArchivo, cantRegistrosDirectorio);

				if (resBorrar == 1) {

					error = escribirTablaDirectorio(&cClusterFte2,
							&cClusterFin2, tablaDirectorio);

					if (!error) {
						if (imprimirDebug) {
							/**/printf(
									"Habilito los clusters correspondientes al archivo.\n");
						}
						uint32_t numClusterArchivo = deInfoANumCluster(
								infoArchivo);
						if (imprimirDebug) {
							/**/
							printf(
									"El primer cluster del archivo es el [%d].\n",
									numClusterArchivo);
						}
						if (numClusterArchivo > 2) {
							nodoCluster* cClusterFte = NULL;
							nodoCluster*cClusterFin = NULL;
							error = obtenerCadenaClusters(numClusterArchivo,
									&cClusterFte, &cClusterFin);

							if (!error) {
								error = habilitarClusters(&cClusterFte,
										&cClusterFin);

								if (!error) {
									return 0;
								} else {
									return -8;
								}
							} else {
								//HUBO UN ERROR AL OBTENER LA CADENA DE CLUSTERS DEL ARCHIVO
								return -7;
							}
						} else if (numClusterArchivo == 0) {
							return 0;
						} else {
							return -6;
						}
					} else {
						//ERROR AL ESCRIBIR LA TABLA DIRECTORIO
						return -5;
					}
				} else {
					//ERROR AL BORRAR LA FILA EN EL DIRECTORIO
					return -4;
				}
			} else {
				//ERROR AL LEER LA TABLA DIRECTORIO
				return -3;
			}
		} else {
			//ERROR AL OBTENER LA CADENA DE CLUSTERS DEL DIRECTORIO
			return -2;
		}
	} else {
		//ERROR AL BUSCAR EL PATH DEL DIRECTORIO
		return -ENOENT;
	}
}
int32_t FLAME_ftruncateAux(const char * path, off_t tamanio,
		struct fuse_file_info * info) {

	if (imprimirDebug) {
		/**/printf(
				"Voy a truncar el archivo con el path [%s] a la longitud [%d].\n",
				path, (int32_t) tamanio);
	}
	char* ruta;
	parsearDir((char*) path, &ruta);

	char* nombre;
	sacarNombreDeRuta((char*) path, &nombre);

	char* nSinExtension;
	parsearNomSinExtension(nombre, &nSinExtension);

	char* extension;
	parsearExtension(nombre, &extension);

	infoArchivoODirectorio infoR;
	div_t division = div(bootSector.rootDirectoryCluster, 256);
	infoR.clusterHighTwoBytes = division.quot;
	infoR.clusterLowTwoBytes = division.rem;
	infoR.attributes = 16;
	int8_t resBusqueda = buscarInfoPathDesdeRaiz(ruta, &infoR);

	if (resBusqueda == -1) {
		return -ENOENT;
	} else {
		if (imprimirDebug) {
			/**/printf(
					"Se encontro algo de tipo [%d] con nombre [%s] y extension [%s].\n",
					infoR.attributes, infoR.name, infoR.extension);
		}

		uint32_t numCluster = deInfoANumCluster(infoR);
		nodoCluster* cClusterFte = NULL;
		nodoCluster* cClusterFteAux = NULL;
		nodoCluster* cClusterFin = NULL;
		nodoCluster* cClusterFinAux = NULL;
		int8_t error = obtenerCadenaClusters(numCluster, &cClusterFte,
				&cClusterFin);

		nodoCluster* aux = cClusterFte;
		while (aux != NULL && !error) {
			error = encolarCluster(&cClusterFteAux, &cClusterFinAux,
					aux->numCluster);
			aux = aux->sig;
		}

		if (!error) {
			uint32_t cantRegistrosDirectorio = tamanioColaClusters(cClusterFte,
					cClusterFin) * bootSector.sectoresCluster
					* bootSector.bytesSector / sizeof(t_registroDirectorio);
			t_registroDirectorio* tablaDirectorio;
			error = leerDirectorio(&cClusterFte, &cClusterFin,
					&tablaDirectorio);

			if (imprimirDebug) {
				/**/
				printf("Primer caracter de la tabla directorio: [%d].\n",
						tablaDirectorio[0].fileName[0]);
			}

			if (!error) {
				infoArchivoODirectorio infoArch;
				strcpy(infoArch.name, nSinExtension);
				strcpy(infoArch.extension, extension);

				int64_t resBusqueda = buscarEnDirectorio(tablaDirectorio,
						&infoArch, cantRegistrosDirectorio);

				if (resBusqueda >= 0) {
					uint64_t sizeAnt = infoArch.size;

					infoArch.size = tamanio;

					resBusqueda = buscarYModificarDirectorio(tablaDirectorio,
							&infoArch, cantRegistrosDirectorio);

					uint32_t numClusterArch = deInfoANumCluster(infoArch);

					if (resBusqueda >= 0) {

						if (numClusterArch > 0 && tamanio >= 0) {

							nodoCluster* cClusterArchFte = NULL;
							nodoCluster* cClusterArchFin = NULL;
							error = obtenerCadenaClusters(numClusterArch,
									&cClusterArchFte, &cClusterArchFin);

							nodoCluster* aux = cClusterArchFte;
							while (aux != NULL) {
								if (imprimirDebug) {
									printf("Cluster: [%d].\n", aux->numCluster);
								}
								aux = aux->sig;
							}
							if (!error) {
								if (imprimirDebug) {
									/**/printf(
											"Se obtuvo una cadena de [%d] clusters.\n",
											tamanioColaClusters(cClusterArchFte,
													cClusterArchFin));
								}
								div_t division = div(
										tamanio,
										(bootSector.sectoresCluster
												* bootSector.bytesSector));
								uint32_t cantClustersNecesarios = 0;
								if (division.rem == 0) {
									cantClustersNecesarios = division.quot;
								} else {
									cantClustersNecesarios = division.quot + 1;
								}
								error = modificarTablaFat(&cClusterArchFte,
										&cClusterArchFin,
										cantClustersNecesarios);

								if (error) {
									//ERROR AL MODIFICAR LA TABLA FAT
									return -6;
								}
							} else {
								//ERROR AL OBTENER LA CADENA DE CLUSTERS
								if (imprimirDebug) {
									/**/printf(
											"Error al obtener la cadena de clusters.\n");
								}
								return -5;
							}

						}

						error = escribirTablaDirectorio(&cClusterFteAux,
								&cClusterFinAux, tablaDirectorio);

						if (!error) {
							if (sizeAnt < tamanio) {
								if (imprimirDebug) {
									/**/printf(
											"Vacio lo que sigue al tamanio truncado.\n");
								}
								uint64_t tamanioAEscribir = tamanio - sizeAnt;
								char* bufferVacio = (char*) malloc(
										tamanioAEscribir);
								memset(bufferVacio, '\0', tamanioAEscribir);
								uint64_t resWrite = FLAME_writeAux(path,
										bufferVacio, (size_t) tamanioAEscribir,
										(off_t) sizeAnt, info);
								printf("aca rompo 2.\n");
								if (resWrite != tamanio) {
									return 0;
								}
							}
							return 0;
						} else {
							//ERROR AL ESCRIBIR LA TABLA DIRECTORIO
							return -4;
						}

					} else {
						//ERROR AL BUSCAR EN EL DIRECTORIO
						return -ENOENT;
					}
				} else {
					//ERROR AL BUSCAR EN EL DIRECTORIO
					return -ENOENT;
				}
			} else {
				//ERROR AL LEER EL DIRECTORIO
				return -2;
			}
		} else {
			//ERROR AL OBTENER UNA CADENA DE CLUSTERS
			return -1;
		}

		//return 0;
	}
}

int32_t FLAME_writeAux(const char* path, char* buf, size_t size, off_t offset,
		struct fuse_file_info* fi) {

	infoArchivoODirectorio info;
	div_t division = div(bootSector.rootDirectoryCluster, 256);
	info.clusterHighTwoBytes = division.quot;
	info.clusterLowTwoBytes = division.rem;
	info.attributes = 16;

	int8_t error = buscarInfoPathDesdeRaiz((char*) path, &info);

	if (!error) {

		if ((offset + size) > info.size) {
			if (imprimirDebug) {
				/**/printf("El tamanio del archivo no alcanza, lo trunco.\n");
			}
			int32_t error = FLAME_ftruncateAux(path, offset + size, fi);
			if (!error) {
				memset(&info, 0, sizeof(infoArchivoODirectorio));
				info.clusterHighTwoBytes = division.quot;
				info.clusterLowTwoBytes = division.rem;
				info.attributes = 16;

				error = buscarInfoPathDesdeRaiz((char*) path, &info);

				if (error) {
					return -ENOENT;
				}
			} else {
				return -14;
			}
		}

		uint32_t numCluster = deInfoANumCluster(info);
		nodoCluster* cClusterFte = NULL;
		nodoCluster* cClusterFin = NULL;
		error = obtenerCadenaClusters(numCluster, &cClusterFte, &cClusterFin);

		if (imprimirDebug) {
			/**/
			printf("La cantidad de clusters del archivo es: [%d].\n",
					tamanioColaClusters(cClusterFte, cClusterFin));
		}

		div_t division2 = div(offset, TAMANIO_BLOQUE);
		uint32_t cantSectoresQNoSeEscriben = division2.quot;

		div_t division3 = div(division2.rem + size, TAMANIO_BLOQUE);
		uint32_t cantClustersAEscribir;
		if (division3.rem == 0) {
			cantClustersAEscribir = division3.quot;
		} else {
			cantClustersAEscribir = division3.quot + 1;
		}

		uint32_t i;
		for (i = 0; i < cantSectoresQNoSeEscriben; i++) {
			if (cClusterFte != NULL) {
				if (imprimirDebug) {
					/**/printf("No tengo que escribir el cluster nro [%d].\n",
							i);
				}
				uint32_t numClusterAux;
				error = desencolarCluster(&cClusterFte, &cClusterFin,
						&numClusterAux);
			} else {
				return -13;
			}
		}

		while (tamanioColaClusters(cClusterFte, cClusterFin)
				> cantClustersAEscribir) {
			if (imprimirDebug) {
				/**/printf("Saco un cluster del final.\n");
			}
			uint32_t numClusterAux;
			desencolarClusterFinal(&cClusterFte, &cClusterFin, &numClusterAux);
		}

		//EMPIEZO A ESCRIBIR LOS BLOQUES
		//PRIMER BLOQUE
		if (cClusterFte != NULL) {
			desencolarCluster(&cClusterFte, &cClusterFin, &numCluster);
			uint64_t sectorInicio = bootSector.sectoresReservados
					+ (bootSector.sectoresPorFat * bootSector.cantidadTablasFat)
					+ (numCluster * bootSector.sectoresCluster);
			uint16_t offsetBloque = division2.rem;
			uint16_t sizeBloque;
			if ((offsetBloque + size) > TAMANIO_BLOQUE) {
				sizeBloque = TAMANIO_BLOQUE;
			} else {
				sizeBloque = size;
			}

			if (imprimirDebug) {
				/**/
				printf("Offset: [%d].\n", offsetBloque);
			}
			if (imprimirDebug) {
				/**/
				printf("Size: [%d].\n", sizeBloque);
			}

			if (imprimirDebug) {
				/**/
				printf("Leo el primer bloque.\n");
			}
			char contenidoAux[TAMANIO_BLOQUE];
			memset(contenidoAux, '\0', TAMANIO_BLOQUE);

			char* contenidoBloqueCache;
			pthread_mutex_lock(&mutexUsandoCache);
			int8_t estaEnCache =
					buscarBloqueEnCache(
							(char*) path,
							(sectorInicio * bootSector.bytesSector
									/ TAMANIO_BLOQUE), &contenidoBloqueCache);
			if (estaEnCache) {
				uint64_t j;
				for (j = 0; j < TAMANIO_BLOQUE; j++) {
					contenidoAux[j] = contenidoBloqueCache[j];
				}
			} else {
				error = leerBloque(sectorInicio, contenidoAux);
				if (error) {
					pthread_mutex_unlock(&mutexUsandoCache);
					return -12;
				}
			}
			pthread_mutex_unlock(&mutexUsandoCache);

			if (!error) {
				if (imprimirDebug) {
					/**/
					printf("Sobreescribo lo necesario.\n");
				}
				uint32_t j;
				for (i = offsetBloque, j = 0; j < sizeBloque; i++, j++) {
					contenidoAux[i] = buf[j];
				}

				if (imprimirDebug) {
					/**/
					printf("Guardo el bloque en cache.\n");
				}
				pthread_mutex_lock(&mutexUsandoCache);
				error = guardarEnCache((char*) path,
						(sectorInicio * bootSector.bytesSector) / TAMANIO_BLOQUE
						, contenidoAux);
				pthread_mutex_unlock(&mutexUsandoCache);

				if (!error) {

					if (imprimirDebug) {
						/**/printf("Escribo el primer bloque.\n");
					}
					error = escribirBloque(sectorInicio, contenidoAux);

					//BLOQUES DEL MEDIO
					if (!error) {
						if (cClusterFte != NULL) {
							i = 0; //PARA QUE i VALGA 0 SI NO ENTRA AL for
							for (i = 0; cClusterFte->sig != NULL && !error;
									i++) {
								//BUSCO HASTA EL ANTEULTIMO
								desencolarCluster(&cClusterFte, &cClusterFin,
										&numCluster);
								uint64_t sectorInicio =
										bootSector.sectoresReservados
												+ (bootSector.sectoresPorFat
														* bootSector.cantidadTablasFat)
												+ (numCluster
														* bootSector.sectoresCluster);
								offsetBloque = 0;
								sizeBloque = TAMANIO_BLOQUE;
								if (imprimirDebug) {
									/**/
									printf("Offset: [%d].\n", offsetBloque);
								}
								if (imprimirDebug) {
									/**/
									printf("Size: [%d].\n", sizeBloque);
								}

								pthread_mutex_lock(&mutexUsandoCache);
								int8_t estaEnCache =
										buscarBloqueEnCache(
												(char*) path,
												(sectorInicio
														* bootSector.bytesSector
														/ TAMANIO_BLOQUE), &contenidoBloqueCache)
												;
								if (estaEnCache) {
									for (j = 0; j < TAMANIO_BLOQUE; j++) {
										contenidoAux[j] =
												contenidoBloqueCache[j];
									}
								} else {
									error = leerBloque(
											sectorInicio,
											buf + division2.rem
													+ (i * TAMANIO_BLOQUE));

									if (error) {
										pthread_mutex_unlock(&mutexUsandoCache);
										return -11;
									}
								}
								if (imprimirDebug) {
									/**/
									printf(
											"Guardo el bloque del medio en la cache.\n");
								}
								error = guardarEnCache(
										(char*) path,
										(sectorInicio * bootSector.bytesSector)
												/ TAMANIO_BLOQUE, contenidoAux);
								pthread_mutex_unlock(&mutexUsandoCache);
							}

							if (!error) {
								if (imprimirDebug) {
									/**/printf(
											"Escribo uno de los clusters del medio.\n");
								}
								error = escribirBloque(
										sectorInicio,
										buf + division2.rem
												+ (i * TAMANIO_BLOQUE));

								//BLOQUE FINAL
								if (!error) {
									if (cClusterFte != NULL) {
										desencolarCluster(&cClusterFte,
												&cClusterFin, &numCluster);
										uint64_t sectorInicio =
												bootSector.sectoresReservados
														+ (bootSector.sectoresPorFat
																* bootSector.cantidadTablasFat)
														+ (numCluster
																* bootSector.sectoresCluster);
										offsetBloque = 0;
										sizeBloque = division3.rem;
										if (imprimirDebug) {
											/**/
											printf("Offset: [%d].\n",
													offsetBloque);
										}
										if (imprimirDebug) {
											/**/
											printf("Size: [%d].\n", sizeBloque);
										}

										if (imprimirDebug) {
											/**/
											printf("Leo el bloque final.\n");
										}
										memset(contenidoAux, '\0',
												TAMANIO_BLOQUE);

										pthread_mutex_lock(&mutexUsandoCache);
										int8_t estaEnCache =
												buscarBloqueEnCache(
														(char*) path,
														(sectorInicio
																* bootSector.bytesSector
																/ TAMANIO_BLOQUE), &contenidoBloqueCache)
														;
										if (estaEnCache) {
											for (j = 0; j < TAMANIO_BLOQUE;
													j++) {
												contenidoAux[j] =
														contenidoBloqueCache[j];
											}
										} else {
											error = leerBloque(sectorInicio,
													contenidoAux);
											if (error) {
												pthread_mutex_unlock(
														&mutexUsandoCache);
												return -10;
											}
										}
										pthread_mutex_unlock(&mutexUsandoCache);

										if (!error) {
											if (imprimirDebug) {
												/**/
												printf(
														"Sobreescribo lo necesario.\n");
											}
											for (j = 0, i = division2.rem
													+ (i * TAMANIO_BLOQUE);
													j < sizeBloque; i++, j++) {
												contenidoAux[j] = buf[i];
											}

											pthread_mutex_lock(
													&mutexUsandoCache);
											if (imprimirDebug) {
												/**/
												printf(
														"Guardo el bloque final en la cache.\n");
											}
											error =
													guardarEnCache(
															(char*) path,
															(sectorInicio
																	* bootSector.bytesSector)
																	/ TAMANIO_BLOQUE
																	,
															contenidoAux);
											pthread_mutex_unlock(
													&mutexUsandoCache);

											if (!error) {
												if (imprimirDebug) {
													/**/printf(
															"Escribo el bloque final.\n");
												}
												error = escribirBloque(
														sectorInicio,
														contenidoAux);
												printf("aca rompo 1\n");
											} else {
												return -9;
											}
										} else {
											return -8;
										}
									} else {
										return -7;
									}
								} else {
									return -6;
								}
							} else {
								return -6;
							}
						}
						if (!error) {
							printf("aca rompo 3.\n");
							return size; //VER QUE DEVUELVE WRITE
						} else {
							return -5;
						}
					} else {
						return -4;
					}
				} else {
					return -3;
				}
			} else {
				return -2;
			}
		} else {
			return -1;
		}
	} else {
		return -ENOENT;
	}
}

int32_t FLAME_renameAux(const char* pathViejo, const char* pathNuevo) {
	int8_t error = 0;

	if (imprimirDebug) {
		/**/
		printf("Se renombrara el path [%s] por [%s].\n", pathViejo, pathNuevo);
	}
	infoArchivoODirectorio infoViejo;
	infoArchivoODirectorio infoNuevo;

	if (imprimirDebug) {
		/**/
		printf("Busco la informacion del archivo a renombrar.\n");
	}
	div_t division = div(bootSector.rootDirectoryCluster, 256);
	infoViejo.clusterHighTwoBytes = division.quot;
	infoViejo.clusterLowTwoBytes = division.rem;
	infoViejo.attributes = 16;
	char* rutaVieja;
	parsearDir((char*) pathViejo, &rutaVieja);
	int8_t resBusqueda = buscarInfoPathDesdeRaiz((char*) pathViejo, &infoViejo);

	if (resBusqueda == 0) {

		infoNuevo.clusterHighTwoBytes = division.quot;
		infoNuevo.clusterLowTwoBytes = division.rem;
		infoNuevo.attributes = 16;
		char* rutaNueva;
		parsearDir((char*) pathNuevo, &rutaNueva);
		int8_t resBusqueda = buscarInfoPathDesdeRaiz((char*) pathNuevo,
				&infoNuevo);

		if (resBusqueda < 0) {

			if (imprimirDebug) {
				/**/
				printf("Copio la informacion del archivo viejo.\n");
			}
			infoNuevo.attributes = infoViejo.attributes;
			infoNuevo.clusterHighTwoBytes = infoViejo.clusterHighTwoBytes;
			infoNuevo.clusterLowTwoBytes = infoViejo.clusterLowTwoBytes;
			infoNuevo.createDate = infoViejo.createDate;
			infoNuevo.createTime = infoViejo.createTime;
			infoNuevo.createTimeFineResolution =
					infoViejo.createTimeFineResolution;
			strcpy(infoNuevo.extension, infoViejo.extension);
			infoNuevo.lastAccessDate = infoViejo.lastAccessDate;
			infoNuevo.lastModifiedDate = infoViejo.lastModifiedDate;
			infoNuevo.lastModifiedTime = infoViejo.lastModifiedTime;
			strcpy(infoNuevo.name, infoViejo.name);
			infoNuevo.reserved = infoViejo.reserved;
			infoNuevo.size = infoViejo.size;

			if (imprimirDebug) {
				/**/
				printf("Borro el archivo viejo.\n");
			}
			struct stat stbuf;
			int32_t resGetattr = FLAME_getattrAux(pathViejo, &stbuf);

			if (resGetattr == 0) {
				int32_t resUnlink = FLAME_unlinkAux(pathViejo);

				if (resUnlink == 0) {
					if (imprimirDebug) {
						/**/
						printf("Creo el archivo nuevo.\n");
					}
					mode_t modo = stbuf.st_mode;
					struct fuse_file_info fInfo;
					FLAME_createAux(pathNuevo, modo, &fInfo);
					infoArchivoODirectorio infoDir;
					infoDir.clusterHighTwoBytes = division.quot;
					infoDir.clusterLowTwoBytes = division.rem;
					infoDir.attributes = 16;
					char* pathDirNuevo = NULL;
					parsearDir((char*) pathNuevo, &pathDirNuevo);
					resBusqueda = buscarInfoPathDesdeRaiz(pathDirNuevo,
							&infoDir);

					if (resBusqueda == 1) {
						nodoCluster* cClusterFte1 = NULL;
						nodoCluster* cClusterFte2 = NULL;
						nodoCluster* cClusterFin1 = NULL;
						nodoCluster* cClusterFin2 = NULL;
						t_registroDirectorio* tablaDirectorio;

						uint32_t numClusterDir = deInfoANumCluster(infoDir);

						if (imprimirDebug) {
							/**/
							printf("Numero del primer cluster: [%d].\n",
									numClusterDir);
						}

						if (numClusterDir > 1) {
							obtenerCadenaClusters(numClusterDir, &cClusterFte1,
									&cClusterFte1);

							nodoCluster* aux = cClusterFte1;
							while (aux != NULL && !error) {
								error = encolarCluster(&cClusterFte2,
										&cClusterFin2, aux->numCluster);
								aux = aux->sig;
							}

							uint16_t cantRegistrosDirectorio =
									tamanioColaClusters(cClusterFte1,
											cClusterFin1)
											* bootSector.sectoresCluster
											* bootSector.bytesSector
											/ sizeof(t_registroDirectorio);
							leerDirectorio(&cClusterFte1, &cClusterFin1,
									&tablaDirectorio);
							infoArchivoODirectorio info;

							char* nombre;
							sacarNombreDeRuta((char*) pathNuevo, &nombre);

							char* nSinExtension;
							parsearNomSinExtension(nombre, &nSinExtension);

							char* extension;
							parsearExtension(nombre, &extension);

							strcpy(info.name, nSinExtension);
							strcpy(info.extension, extension);

							if (imprimirDebug) {
								/**/
								printf(
										"Primer caracter de la tabla directorio: [%d].\n",
										tablaDirectorio[0].fileName[0]);
							}
							int64_t i = buscarEnDirectorio(tablaDirectorio,
									&info, cantRegistrosDirectorio);

							if (imprimirDebug) {
								/**/
								printf("i vale: [%d].\n", i);
							}
							if (i >= 0) {
								tablaDirectorio[i].fileAttributes =
										infoNuevo.attributes;
								tablaDirectorio[i].reserved =
										infoNuevo.reserved;
								tablaDirectorio[i].createTime =
										infoNuevo.createTime;
								tablaDirectorio[i].createTimeFineResolution =
										infoNuevo.createTimeFineResolution;
								tablaDirectorio[i].createDate =
										infoNuevo.createDate;
								tablaDirectorio[i].lastAccessDate =
										infoNuevo.lastAccessDate;
								tablaDirectorio[i].high2BytesOfCluster =
										infoNuevo.clusterHighTwoBytes;
								tablaDirectorio[i].lastModifiedTime =
										infoNuevo.lastModifiedTime;
								tablaDirectorio[i].lastModifiedDate =
										infoNuevo.lastModifiedDate;
								tablaDirectorio[i].low2BytesOfCluster =
										infoNuevo.clusterLowTwoBytes;
								tablaDirectorio[i].fileSize = infoNuevo.size;
								int8_t error = escribirTablaDirectorio(
										&cClusterFte2, &cClusterFin2,
										tablaDirectorio);
								if (error) {
									return -8;
								} else {
									return 0;
								}

							} else {
								return -7;
							}
						} else {
							return -6;
						}
					} else {
						return -5;
					}
				} else {
					//ERROR EN EL UNLINK
					return -4;
				}
			} else {
				//ERROR EN EL GETATTR
				return -3;
			}
		} else {
			//EL ARCHIVO DEL PATH NUEVO YA EXISTE
			return -2;
		}
	} else {
		if (imprimirDebug) {
			/**/printf("No se encontro un archivo con ese path.\n");
		}
		return -ENOENT;
	}
}

int32_t FLAME_releaseAux(const char* path, struct fuse_file_info* info) {
	t_nodoCache* p = buscarPathEnListaCache(path);
	if (p != NULL) {
		if (p->cantFileDescriptor == 0) {
			FLAME_flushAux(path, info);
		} else {
			p->cantFileDescriptor--;
			if (p->cantFileDescriptor == 0) {
				FLAME_flushAux(path, info);
			}
		}
	} else {
		return -1;
	}
	return 0;
}
